package com.adcc.loadsheet.monitor.entity;

import com.adcc.loadsheet.monitor.util.AlarmEnum;
import com.adcc.loadsheet.monitor.util.Constant;
import com.adcc.loadsheet.monitor.util.StringUtil;

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ArrayBlockingQueue;

/**
 * MsgUpCenter监控信息实体
 */
public class MsgUpCenterMonitor extends BaseEntity implements Cloneable {

    // 远程时间（运行程序的本地时间）
    private String remoteDateTime;

    // 本地时间（本地进行NTP授时，即NTP时间）
    private String localDateTime;

    // 时间分钟差
    private int minutesBetween;

    // NTP状态
    private boolean ntpStatus;

    // 上行状态（ACARS接收）
    private boolean uplinkStatus;

    // 下行状态（ACARS发送）
    private boolean downlinkStatus;

    // 报文总数
    private long totalCount;

    // 舱单报文数
    private long loadsheetCount;

    // 名单报文数
    private long passgerlistCount;

    // 错误报文数
    private long failCount;

    // 监控状态
    private MonitorStatus status = MonitorStatus.ABNORMAL;

    // 异常状态码(0：正常，1：异常，状态机:000,例如111标识模块监控项均异常)
    private String errorCode = "000";

    // 异常原因：XXX IS DOWN,XXX IS DOWN
    private String errorReason = "";

    // 本模块异常的节点
    private Set<String> alarmContent = new HashSet<>();

    // 本模块正常的节点（用于判断告警确认后，部分节点正常后又异常需要重新告警）
    private Set<String> unAlarmContent = new HashSet<>();

    // 舱单统计数据队列
    private ArrayBlockingQueue<Long> loadsheetData;

    // 名单统计数据队列
    private ArrayBlockingQueue<Long> passgerlistData;

    // 最后一次统计数据更新时间
    private long updateTime;

    // 时间跨度（折线图X轴时间刻度）
    private int timespan;

    // 数据个数（折线图数据点）
    private int points;

    public String getRemoteDateTime() {
        return remoteDateTime;
    }

    public void setRemoteDateTime(String remoteDateTime) {
        this.remoteDateTime = remoteDateTime;
    }

    public String getLocalDateTime() {
        return localDateTime;
    }

    public void setLocalDateTime(String localDateTime) {
        this.localDateTime = localDateTime;
    }

    public int getMinutesBetween() {
        return minutesBetween;
    }

    public void setMinutesBetween(int minutesBetween) {
        this.minutesBetween = minutesBetween;
    }

    public boolean isNtpStatus() {
        return ntpStatus;
    }

    public void setNtpStatus(boolean ntpStatus) {
        this.ntpStatus = ntpStatus;
    }

    public boolean isUplinkStatus() {
        return uplinkStatus;
    }

    public void setUplinkStatus(boolean uplinkStatus) {
        this.uplinkStatus = uplinkStatus;
    }

    public boolean isDownlinkStatus() {
        return downlinkStatus;
    }

    public void setDownlinkStatus(boolean downlinkStatus) {
        this.downlinkStatus = downlinkStatus;
    }

    public long getTotalCount() {
        return totalCount;
    }

    public void setTotalCount(long totalCount) {
        this.totalCount = totalCount;
    }

    public long getLoadsheetCount() {
        return loadsheetCount;
    }

    public void setLoadsheetCount(long loadsheetCount) {
        this.loadsheetCount = loadsheetCount;
    }

    public long getPassgerlistCount() {
        return passgerlistCount;
    }

    public void setPassgerlistCount(long passgerlistCount) {
        this.passgerlistCount = passgerlistCount;
    }

    public long getFailCount() {
        return failCount;
    }

    public void setFailCount(long failCount) {
        this.failCount = failCount;
    }

    public MonitorStatus getStatus() {
        return status;
    }

    public void setStatus(MonitorStatus status) {
        this.status = status;
    }

    public String getErrorCode() {
        return errorCode;
    }

    public void setErrorCode(String errorCode) {
        this.errorCode = errorCode;
    }

    public String getErrorReason() {
        return errorReason;
    }

    public void setErrorReason(String errorReason) {
        this.errorReason = errorReason;
    }

    public Set<String> getAlarmContent() {
        return alarmContent;
    }

    public void setAlarmContent(Set<String> alarmContent) {
        this.alarmContent = alarmContent;
    }

    public Set<String> getUnAlarmContent() {
        return unAlarmContent;
    }

    public void setUnAlarmContent(Set<String> unAlarmContent) {
        this.unAlarmContent = unAlarmContent;
    }

    public ArrayBlockingQueue<Long> getLoadsheetData() {
        return loadsheetData;
    }

    public void setLoadsheetData(ArrayBlockingQueue<Long> loadsheetData) {
        this.loadsheetData = loadsheetData;
    }

    public ArrayBlockingQueue<Long> getPassgerlistData() {
        return passgerlistData;
    }

    public void setPassgerlistData(ArrayBlockingQueue<Long> passgerlistData) {
        this.passgerlistData = passgerlistData;
    }

    public long getUpdateTime() {
        return updateTime;
    }

    public void setUpdateTime(long updateTime) {
        this.updateTime = updateTime;
    }

    public int getTimespan() {
        return timespan;
    }

    public void setTimespan(int timespan) {
        this.timespan = timespan;
    }

    public int getPoints() {
        return points;
    }

    public void setPoints(int points) {
        this.points = points;
    }

    @Override
    public String toXML() throws Exception {
        return null;
    }

    @Override
    public String toJSON() throws Exception {
        return null;
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        MsgUpCenterMonitor msgUpCenter = new MsgUpCenterMonitor();
        msgUpCenter.setRemoteDateTime(remoteDateTime);
        msgUpCenter.setLocalDateTime(localDateTime);
        msgUpCenter.setMinutesBetween(minutesBetween);
        msgUpCenter.setNtpStatus(ntpStatus);
        msgUpCenter.setUplinkStatus(uplinkStatus);
        msgUpCenter.setDownlinkStatus(downlinkStatus);
        msgUpCenter.setTotalCount(totalCount);
        msgUpCenter.setLoadsheetCount(loadsheetCount);
        msgUpCenter.setPassgerlistCount(passgerlistCount);
        msgUpCenter.setFailCount(failCount);
        msgUpCenter.setStatus(status);
        msgUpCenter.setErrorCode(errorCode);
        msgUpCenter.setErrorReason(errorReason);
        msgUpCenter.setAlarmContent(alarmContent);
        msgUpCenter.setUnAlarmContent(unAlarmContent);
        msgUpCenter.setLoadsheetData(loadsheetData);
        msgUpCenter.setPassgerlistData(passgerlistData);
        msgUpCenter.setUpdateTime(updateTime);
        msgUpCenter.setTimespan(timespan);
        msgUpCenter.setPoints(points);
        return msgUpCenter;
    }

    /**
     * 异常状态码
     */
    public void buildErrorCode() {
        StringBuilder sb = new StringBuilder();
        char[] states = new char[3];
        states[0] = ntpStatus ? '0' : '1';
        states[1] = uplinkStatus ? '0' : '1';
        states[2] = downlinkStatus ? '0' : '1';
        for(char c : states){
            sb.append(c);
        }
        this.errorCode = sb.toString();

        // [2024-6-01：张丽娟：增加声音和弹窗告警的功能，系统支持对指定告警项进行声音和弹窗告警忽略的功能: 根据状态码获取正常节点和异常节点信息]
        // 本模块异常的节点
        Set<String> alarmContent = new HashSet<>();
        // 本模块正常的节点（用于判断告警确认后，部分节点正常后又异常需要重新告警）
        Set<String> unAlarmContent = new HashSet<>();
        // 保存到数据库的异常信息
        StringBuilder errorReasonBuilder = new StringBuilder();

        AlarmEnum enumNtp = AlarmEnum.MSGUPCENTER_NTP;
        if (states[0] == '1') {
            errorReasonBuilder.append(String.format(Constant.LOG_DOWN, enumNtp.getMysqlLogName()));
            alarmContent.add(enumNtp.getItem());
        }else{
            unAlarmContent.add(enumNtp.getItem());
        }

        AlarmEnum enumDownlink = AlarmEnum.MSGUPCENTER_DOWNLINK;
        if (states[1] == '1') {
            errorReasonBuilder.append(String.format(Constant.LOG_DOWN, enumDownlink.getMysqlLogName()));
            alarmContent.add(enumDownlink.getItem());
        }else{
            unAlarmContent.add(enumDownlink.getItem());
        }

        AlarmEnum enumUplink = AlarmEnum.MSGUPCENTER_UPLINK;
        if (states[2] == '1') {
            errorReasonBuilder.append(String.format(Constant.LOG_DOWN, enumUplink.getMysqlLogName()));
            alarmContent.add(enumUplink.getItem());
        }else{
            unAlarmContent.add(enumUplink.getItem());
        }

        this.alarmContent = alarmContent;
        this.unAlarmContent = unAlarmContent;
        this.errorReason = StringUtil.stringBuilderToString(errorReasonBuilder);
    }
}
